Package weasel.compiler

Source Code of weasel.compiler.WeaselTokenParser

package weasel.compiler;

import java.io.EOFException;

import weasel.compiler.keywords.WeaselKeyWord;

public class WeaselTokenParser {

  private String source;
  private int pos;
  private int line;
  private boolean isEOFOk=true;
 
  public WeaselTokenParser(String source){
    this.source = source;
    pos = 0;
    line = 1;
  }
 
  public WeaselToken getNextToken() throws WeaselSyntaxError{
    isEOFOk=true;
    try{
      char c = skipWhiteSpace();
      if(isAlphabetical(c)){
        isEOFOk = false;
        String ident="";
        while(isAlphabetical(c)||isDigit(c)){
          ident += c;
          c = readNextChar();
        }
        readPrevChar();
        if(ident.equals("true")){
          return new WeaselToken(WeaselTokenType.BOOL, line, true);
        }else if(ident.equals("false")){
          return new WeaselToken(WeaselTokenType.BOOL, line, false);
        }else if(ident.equals("null")){
          return new WeaselToken(WeaselTokenType.NULL, line, null);
        }
        int modifier = WeaselModifierMap.getModifier(ident);
        if(modifier!=0){
          return new WeaselToken(WeaselTokenType.MODIFIER, line, modifier);
        }
        WeaselKeyWord wkw = WeaselKeyWord.getWeaselKeyWord(ident);
        if(wkw!=null){
          return new WeaselToken(WeaselTokenType.KEYWORD, line, wkw);
        }
        return new WeaselToken(WeaselTokenType.IDENT, line, ident);
      }
      if(isDigit(c) || c=='.'){
        isEOFOk = false;
        boolean isDot = c=='.';
        int num=0;
        if(c=='0'){
          c = readNextChar();
          if(c=='x'){
            c = readNextChar();
            if(!(isDigit(c) || (c>='a' && c<='f') || (c>='A' && c<='F')))
              throw new WeaselSyntaxError(line, "Expect hex but got "+c);
            while(true) {
              if(isDigit(c)){
                num<<=4;
                num+=c-'0';
              }else if(c>='a' && c<='f'){
                num<<=4;
                num+=c-'a'+10;
              }else if(c>='A' && c<='F'){
                num<<=4;
                num+=c-'A'+10;
              }else if(isAlphabetical(c)){
                throw new WeaselSyntaxError(line, "Expect hex but got "+c);
              }else{
                break;
              }
              c = readNextChar();
            }
            readPrevChar();
            return new WeaselToken(WeaselTokenType.INTEGER, line, num);
          }else if(c=='b'){
            c = readNextChar();
            if(!(c=='0' || c=='1'))
              throw new WeaselSyntaxError(line, "Expect bit but got "+c);
            while(true) {
              if(c=='0' || c=='1'){
                num<<=1;
                if(c=='1')
                  num++;
              }else if(isDigit(c)||isAlphabetical(c)){
                throw new WeaselSyntaxError(line, "Expect bit but got "+c);
              }else{
                break;
              }
              c = readNextChar();
            }
            readPrevChar();
            return new WeaselToken(WeaselTokenType.INTEGER, line, num);
          }
        }
        while(isDigit(c)){
          num *= 10;
          num += c-'0';
          c = readNextChar();
        }
        if(c=='.'){
          c = readNextChar();
          if(!isDot || isDigit(c)){
            int d=0;
            int i=1;
            while(isDigit(c)){
              d += c-'0';
              i *= 10;
              c = readNextChar();
            }
            readPrevChar();
            return new WeaselToken(WeaselTokenType.DOUBLE, line, num+(double)d/i);
          }
          c = readPrevChar();
        }else if(isAlphabetical(c)){
          throw new WeaselSyntaxError(line, "Expect number but got "+c);
        }else{
          readPrevChar();
          return new WeaselToken(WeaselTokenType.INTEGER, line, num);
        }
      }
      isEOFOk = true;
      if(c=='"'){
        isEOFOk = false;
        c = readNextChar();
        String s="";
        while(c!='"'){
          if(c=='\\'){
            c = readNextChar();
            switch(c){
            case 'n':
              s+='\n';
              break;
            case 't':
              s+='\t';
              break;
            case '\\':
              s+='\\';
              break;
            default:
              throw new WeaselSyntaxError(line, "Expect \n, \t or \\");
            }
          }else{
            s += c;
          }
          c = readNextChar();
        }
        return new WeaselToken(WeaselTokenType.STRING, line, s);
      }
      WeaselTokenType wtt = WeaselTokenType.getTokenTypeFor(""+c, false);
      if(wtt!=null){
        return new WeaselToken(wtt, line);
      }
      WeaselOperator lastFullEqual = null;
      boolean again = true;
      String s="";
      int back=0;
      isEOFOk = false;
      while(again){
        again = false;
        s+=c;
        for(WeaselOperator wo:WeaselOperator.values()){
          if(wo.name.equals(s)){
            lastFullEqual = wo;
            back = 0;
          }else if(wo.name.startsWith(s)){
            again = true;
          }
        }
        back++;
        c=readNextChar();
      }
      isEOFOk = true;
      while(back>0){
        back--;
        c = readPrevChar();
      }
      if(lastFullEqual!=null){
        return new WeaselToken(WeaselTokenType.OPERATOR, line, lastFullEqual);
      }
      wtt = WeaselTokenType.getTokenTypeFor(""+c, true);
      if(wtt!=null){
        return new WeaselToken(wtt, line);
      }
      throw new WeaselSyntaxError(line, "Unexpected char "+c);
    }catch(EOFException e){
      if(isEOFOk){
        return new WeaselToken(WeaselTokenType.NONE, line);
      }
      throw new WeaselSyntaxError(line, "Unexpect end of file");
    }
  }
 
  private boolean isSpace(char c){
    return c==' '||c=='\t'||c=='\r'||c=='\n';
  }
 
  private boolean isDigit(char c){
    return c>='0' && c<='9';
  }
 
  private boolean isAlphabetical(char c){
    return (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_';
  }
 
  private char skipWhiteSpace() throws EOFException{
    int length = source.length();
    if(length<=pos){
      throw new EOFException();
    }
    char c = source.charAt(pos);
    pos++;
    while(isSpace(c)){
      if(c=='\n')
        line++;
      if(length<=pos){
        throw new EOFException();
      }
      c = source.charAt(pos);
      pos++;
    }
    if(c=='/'){
      c = readNextChar();
      if(c=='/'){
        while(readNextChar()!='\n');
        return skipWhiteSpace();
      }else if(c=='*'){
        isEOFOk=false;
        while(true){
          c=readNextChar();
          if(c=='*'){
            c=readNextChar();
            if(c=='/')
              break;
          }
        }
        isEOFOk=true;
        return skipWhiteSpace();
      }else{
        c = readPrevChar();
      }
    }
    return c;
  }
 
  private char readNextChar() throws EOFException{
    int length = source.length();
    if(length<=pos){
      throw new EOFException();
    }
    char c = source.charAt(pos);
    pos++;
    if(c=='\n')
      line++;
    return c;
  }
 
  private char readPrevChar() throws EOFException{
    pos--;
    if(pos<=0){
      throw new EOFException();
    }
    char c = source.charAt(pos);
    if(c=='\n')
      line--;
    pos--;
    c = source.charAt(pos);
    pos++;
    return c;
  }

  public int getLine() {
    return line;
  }
 
}
TOP

Related Classes of weasel.compiler.WeaselTokenParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.